import { Server, Socket } from 'socket.io';
import { EventEmitter } from 'events';
import { 
  ServerToClientEvents, 
  ClientToServerEvents, 
  InterServerEvents, 
  SocketData 
} from '../types';

interface WebSocketClient {
  socket: Socket<ClientToServerEvents, ServerToClientEvents, InterServerEvents, SocketData>;
  deviceId: string;
  lastPing: number;
  messageCount: number;
}

export class WebSocketService extends EventEmitter {
  private io: Server<ClientToServerEvents, ServerToClientEvents, InterServerEvents, SocketData>;
  private clients: Map<string, WebSocketClient> = new Map();
  private deviceSockets: Map<string, Set<string>> = new Map();

  constructor(io: Server<ClientToServerEvents, ServerToClientEvents, InterServerEvents, SocketData>) {
    super();
    this.io = io;
    this.setupSocketHandlers();
  }

  // 设置Socket.io事件处理器
  private setupSocketHandlers(): void {
    this.io.on('connection', (socket) => {
      console.log(`WebSocket连接建立: ${socket.id}`);
      
      // 设备注册
      socket.on('device:register', (deviceInfo: any) => {
        this.handleDeviceRegister(socket, deviceInfo);
      });

      // 配对相关事件
      socket.on('pairing:generate-code', () => {
        this.handleGeneratePairingCode(socket);
      });

      socket.on('pairing:use-code', (data: { code: string }) => {
        console.log('🔍 [websocketservice.ts,pairing:use-code;PAIRING] 使用配对码进行配对: ', data.code);
        this.handleUsePairingCode(socket, data);
      });

      // 语音相关事件
      socket.on('voice:send-text', (data: any) => {
        this.handleVoiceSendText(socket, data);
      });

      socket.on('voice:recognize', (data: any) => {
        this.handleVoiceRecognize(socket, data);
      });

      // 流式语音事件
      socket.on('voice:stream/start', (params?: any) => {
        this.handleVoiceStreamStart(socket, params);
      });

      socket.on('voice:stream/data', (audioChunk: any) => {
        this.handleVoiceStreamData(socket, audioChunk);
      });

      socket.on('voice:stream/end', () => {
        this.handleVoiceStreamEnd(socket);
      });

      // 设备管理事件
      socket.on('device:get-list', () => {
        this.handleGetDeviceList(socket);
      });

      socket.on('device:pair', (data: { pairingCode: string }) => {
        this.handleDevicePair(socket, data);
      });

      socket.on('device:get-pairing-status', (data: { deviceId: string }) => {
        this.handleGetPairingStatus(socket, data);
      });

      // 系统事件
      socket.on('system:heartbeat', () => {
        this.handleHeartbeat(socket);
      });

      // 连接断开
      socket.on('disconnect', (reason) => {
        this.handleDisconnect(socket, reason);
      });
    });
  }

  // 设备注册处理
  private handleDeviceRegister(socket: Socket, deviceInfo: any): void {
    try {
      // 这里需要访问DeviceManager，通过事件传递
      this.emit('device:register', { socket, deviceInfo });
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Unknown error';
      socket.emit('device:registered', {
        success: false,
        deviceId: '',
        message: errorMessage
      });
    }
  }

  // 生成配对码处理
  private handleGeneratePairingCode(socket: Socket): void {
    try {
      this.emit('pairing:generate-code', { socket });
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Unknown error';
      socket.emit('pairing:failed', { message: errorMessage });
    }
  }

  // 使用配对码处理
  private handleUsePairingCode(socket: Socket, data: { code: string }): void {
    try {
      this.emit('pairing:use-code', { socket, data });
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Unknown error';
      socket.emit('pairing:failed', { message: errorMessage });
    }
  }

  // 语音文字发送处理
  private handleVoiceSendText(socket: Socket, data: any): void {
    try {
      this.emit('voice:send-text', { socket, data });
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Unknown error';
      socket.emit('voice:error', { message: errorMessage });
    }
  }

  // 语音识别处理
  private handleVoiceRecognize(socket: Socket, data: any): void {
    try {
      this.emit('voice:recognize', { socket, data });
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Unknown error';
      socket.emit('voice:result', {
        success: false,
        error: errorMessage,
        timestamp: Date.now()
      });
    }
  }

  // 流式语音开始
  private handleVoiceStreamStart(socket: Socket, params?: any): void {
    try {
      this.emit('voice:stream/start', { socket, params });
    } catch (error) {
      console.error('流式语音开始失败:', error);
    }
  }

  // 流式语音数据
  private handleVoiceStreamData(socket: Socket, audioChunk: any): void {
    try {
      this.emit('voice:stream/data', { socket, audioChunk });
    } catch (error) {
      console.error('流式语音数据处理失败:', error);
    }
  }

  // 流式语音结束
  private handleVoiceStreamEnd(socket: Socket): void {
    try {
      this.emit('voice:stream/end', { socket });
    } catch (error) {
      console.error('流式语音结束失败:', error);
    }
  }

  // 获取设备列表
  private handleGetDeviceList(socket: Socket): void {
    try {
      this.emit('device:get-list', { socket });
    } catch (error) {
      console.error('获取设备列表失败:', error);
    }
  }

  // 设备配对
  private handleDevicePair(socket: Socket, data: { pairingCode: string }): void {
    try {
      this.emit('device:pair', { socket, data });
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Unknown error';
      socket.emit('device:pair:result', { success: false, error: errorMessage });
    }
  }

  // 获取配对状态
  private handleGetPairingStatus(socket: Socket, data: { deviceId: string }): void {
    try {
      this.emit('device:get-pairing-status', { socket, data });
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Unknown error';
      socket.emit('device:pairing-status', { success: false, error: errorMessage });
    }
  }

  // 心跳处理
  private handleHeartbeat(socket: Socket): void {
    const client = this.clients.get(socket.id);
    if (client) {
      client.lastPing = Date.now();
    }
  }

  // 连接断开处理
  private handleDisconnect(socket: Socket, reason: string): void {
    console.log(`WebSocket连接断开: ${socket.id} (原因: ${reason})`);
    this.removeClient(socket.id);
  }

  // 添加客户端
  addClient(socketId: string, deviceId: string, socket: Socket): void {
    const client: WebSocketClient = {
      socket,
      deviceId,
      lastPing: Date.now(),
      messageCount: 0
    };

    this.clients.set(socketId, client);
    this.addToDeviceGroup(deviceId, socketId);
  }

  // 移除客户端
  removeClient(socketId: string): void {
    const client = this.clients.get(socketId);
    if (client) {
      this.clients.delete(socketId);
      
      // 从设备分组中移除
      const deviceSockets = this.deviceSockets.get(client.deviceId);
      if (deviceSockets) {
        deviceSockets.delete(socketId);
        if (deviceSockets.size === 0) {
          this.deviceSockets.delete(client.deviceId);
        }
      }
    }
  }

  // 添加到设备分组
  private addToDeviceGroup(deviceId: string, socketId: string): void {
    if (!this.deviceSockets.has(deviceId)) {
      this.deviceSockets.set(deviceId, new Set());
    }
    this.deviceSockets.get(deviceId)!.add(socketId);
  }

  // 发送消息到特定Socket
  sendToSocket(socketId: string, event: string, data: any): void {
    const client = this.clients.get(socketId);
    if (client) {
      client.socket.emit(event as any, data);
      client.messageCount++;
      client.lastPing = Date.now();
    }
  }

  // 发送消息到设备的所有Socket
  sendToDevice(deviceId: string, event: string, data: any): void {
    const socketIds = this.deviceSockets.get(deviceId);
    if (socketIds) {
      socketIds.forEach(socketId => {
        this.sendToSocket(socketId, event, data);
      });
    }
  }

  // 广播消息到所有客户端
  broadcast(event: string, data: any): void {
    this.io.emit(event as any, data);
  }

  // 连接状态查询
  hasConnection(deviceId: string): boolean {
    const socketIds = this.deviceSockets.get(deviceId);
    return socketIds ? socketIds.size > 0 : false;
  }

  // 获取设备的所有WebSocket连接
  getDeviceConnections(deviceId: string): string[] {
    const socketIds = this.deviceSockets.get(deviceId);
    return socketIds ? Array.from(socketIds) : [];
  }

  // 获取连接统计
  getConnectionStats() {
    return {
      totalClients: this.clients.size,
      deviceCount: this.deviceSockets.size,
      devices: Array.from(this.deviceSockets.keys())
    };
  }

  // 清理过期连接
  cleanup(): void {
    const now = Date.now();
    const expiredClients: string[] = [];

    this.clients.forEach((client, socketId) => {
      if (now - client.lastPing > 300000) { // 5分钟超时
        expiredClients.push(socketId);
      }
    });

    expiredClients.forEach(socketId => {
      this.removeClient(socketId);
    });

    if (expiredClients.length > 0) {
      console.log(`清理了 ${expiredClients.length} 个过期的WebSocket连接`);
    }
  }
} 